package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.heima.clients.article.IArticleClient;
import com.heima.clients.schedule.ITaskClient;
import com.heima.common.redis.CacheService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.BaiduScanService;
import com.heima.wemedia.service.WmAutoScanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiaquanen
 * @version 1.0
 * @project heima-leadnews
 * @date 2024/7/23 11:34:57
 */
@Service
public class WmAutoScanServiceImpl implements WmAutoScanService {

    @Autowired
    private BaiduScanService baiduScanService;;
    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Qualifier("iArticleClient")
    @Autowired
    private IArticleClient iArticleClient;

    @Autowired
    private WmUserMapper wmUserMapper;

    @Autowired
    private WmChannelMapper wmChannelMapper;

    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;

    @Autowired
    private CacheService cacheService;


    /**
     * 提交审核
     *
     * @param id
     */
    @Override
    public void autoScanWmNews(Integer id) {
        //根据文章id查询文章
        WmNews wmNews = wmNewsMapper.selectById(id);
        //校验文章的状态
        if(wmNews==null||wmNews.getStatus()!=1)
            throw new RuntimeException("文章状态不对");
        //获取文章的文本内容和图片内容
        HashMap<String,Object> hashMap=getContentAndImage(wmNews);
        //对文本信息进行审核
        boolean passText = isTextPass((String) hashMap.get("content"), wmNews);
        if (!passText)
            return;
        //对图片信息进行审核
        boolean passImage=ImagePass((Set<String>) hashMap.get("image"),wmNews);
        if(!passImage) return;

        //调用feign进行文章同步到用户端
        insertOrUpdate(wmNews);
    }

    /**
     * 获取文章中的文本和图片
     *
     * @param wmNews
     * @return
     */
    private HashMap<String, Object> getContentAndImage(WmNews wmNews) {
        HashMap<String,Object> hashMap=new HashMap<>();
        //定义一个stringBuilder用于存放文本信息
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(wmNews.getTitle());
        stringBuilder.append(wmNews.getLabels());

        //定义一个Set集合存放图片的url
        Set<String> hashSet = new HashSet<>();

        //先将封面图片存放进来
        if(wmNews.getImages()!=null) {
            String[] split = wmNews.getImages().split(",");
            Collections.addAll(hashSet, split);
        }

        //开始对文章内容进行遍历
        String content = wmNews.getContent();
        JSONArray jsonArray = JSONArray.parseArray(content);
        for (Object object : jsonArray) {
            JSONObject jsonObject = JSONObject.parseObject(object.toString());
            if(jsonObject.getString("type").equals("text"))
            {
                stringBuilder.append(jsonObject.getString("value"));
            }
            else if(jsonObject.getString("type").equals("image"))
            {
                hashSet.add(jsonObject.getString("value"));
            }
        }
        //将数据封装进入map集合
        hashMap.put("content",stringBuilder.toString());
        hashMap.put("image",hashSet);
        return hashMap;
    }

    /**
     * 文本内容审核
     *
     * @param content
     * @param wmNews
     * @return
     */
    private boolean isTextPass(String content, WmNews wmNews) {
        //先进行内审
         //添加缓存,先去缓存中去拿，缓存中如果没有再去查数据库，查完再更新缓存
        String string = cacheService.get("sensitive");
        List<String> sensitive = JSONArray.parseArray(string, String.class);
        if(sensitive==null||sensitive.isEmpty())
        {
            //查询鸣高词库中的敏感词放入map集合中去
            List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(null);
            sensitive = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
            //将数据库中的数据添加到缓存中去
            cacheService.set("sensitive", JSONArray.toJSONString(sensitive));
        }
        //将敏感词初始化到map集合中去
        SensitiveWordUtil.initMap(sensitive);
        //将文章进行初审查
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(content);
        //审核不通过，直接pass，通过的话再交给外审
        if(!stringIntegerMap.isEmpty())
        {
            //审核不通过
            passTextOrImage(wmNews, WmNews.Status.FAIL, "审核不通过，文章中存在不合法词汇");
            return false;
        }

        //再调用外部接口审核
        Integer integer = baiduScanService.scanText(content);
        if(integer==2)
        {
            //审核不通过
            passTextOrImage(wmNews, WmNews.Status.FAIL, "审核不通过，文章中存在不合法词汇");
            return false;
        }else if(integer==3||integer==4)
        {
            //要交给人工审核
            passTextOrImage(wmNews, WmNews.Status.ADMIN_AUTH, "文章需要交给人工审核");
            return false;
        }
        return true;
    }

    /**
     * 图片内容审核
     *
     * @param images
     * @param wmNews
     * @return
     */
    private boolean ImagePass(Set<String> images, WmNews wmNews) {
     /*   try {
            //先进行内审
            for (String image : images) {
                byte[] bytes = minIOTemplate.downLoadFile(image);
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
                BufferedImage read = ImageIO.read(byteArrayInputStream);
                String string = tess4jClient.doOCR(read);
                if(!StringUtils.isEmpty(string))
                {
                    boolean pass = isTextPass(string, wmNews);
                    if(!pass)
                    {
                        passTextOrImage(wmNews, WmNews.Status.FAIL, "审核不通过，图片中存在不合法词汇");
                        return false;
                    }
                }
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }*/
        //再调用外部接口审核
        for (String image : images) {
            Integer integer = baiduScanService.scanImage(image);
            if(integer==2)
            {
                //审核不通过
                passTextOrImage(wmNews, WmNews.Status.FAIL, "审核不通过，图片中存在不合法词汇");
                return false;
            }else if(integer==3||integer==4)
            {
                //要交给人工审核
                passTextOrImage(wmNews, WmNews.Status.ADMIN_AUTH, "文章需要交给人工审核");
                return false;
            }
        }
        //此时可以将文章的信息改为审核通过了
        passTextOrImage(wmNews, WmNews.Status.SUCCESS, "文章审核通过");
        return true;
    }

    /**
     * 更新文章审核情况
     *
     * @param wmNews
     * @param fail
     * @param reason
     */
    private void passTextOrImage(WmNews wmNews,WmNews.Status fail, String reason) {
        wmNews.setStatus(fail.getCode());
        wmNews.setReason(reason);
        wmNewsMapper.updateById(wmNews);
    }

    /**
     * 调用feign进行文章同步到用户端
     *
     * @param wmNews
     */
    private void insertOrUpdate(WmNews wmNews) {
        //进行实体类的封装数据
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        //articleDto中还有一些数据需要单独封装id,authorId,authorName,channelName,la
        if(wmNews.getArticleId()!=null)
        {
            articleDto.setId(wmNews.getArticleId());
        }
        //根据用户id去用户表中查找用户名称
        String userName = wmUserMapper.selectById(wmNews.getUserId()).getName();
        articleDto.setAuthorId(Long.valueOf(wmNews.getUserId()));
        articleDto.setAuthorName(userName);
        //频道名称的封装
        String channelName = wmChannelMapper.selectById(wmNews.getChannelId()).getName();
        articleDto.setChannelName(channelName);
        //封装标签
        articleDto.setLayout(wmNews.getType());

        //数据封装完成进行feign的远程调用
        ResponseResult responseResult=iArticleClient.syncArticle(articleDto);
        //获取返回的文章id
        if(responseResult.getCode()==200)
            wmNews.setArticleId(Long.valueOf(responseResult.getData().toString()));
        passTextOrImage(wmNews, WmNews.Status.PUBLISHED, "文章审核通过");
    }
}
